#include "stdafx.h"

#include "common_park.h"

CString FileUtils::GetExtName(const CString filePath)
{
	CString tmpFilePath = filePath;
	TCHAR tmpDrive[8] = _T("");
	TCHAR tmpDir[MAX_PATH] = _T("");
	TCHAR tmpFilename[MAX_PATH] = _T("");
	TCHAR tmpExt[MAX_PATH] = _T("");

	_tsplitpath_s(tmpFilePath.GetBuffer(tmpFilePath.GetLength()),
		tmpDrive, sizeof(tmpDrive) / sizeof(TCHAR),
		tmpDir, sizeof(tmpDir) / sizeof(TCHAR),
		tmpFilename, sizeof(tmpFilename) / sizeof(TCHAR),
		tmpExt, sizeof(tmpExt) / sizeof(TCHAR));

	return (CString)tmpExt;
}

CString FileUtils::GetOnlyFileName(const CString filePath)
{
	CString tmpFilePath = filePath;
	TCHAR tmpDrive[8] = _T("");
	TCHAR tmpDir[MAX_PATH] = _T("");
	TCHAR tmpFilename[MAX_PATH] = _T("");
	TCHAR tmpExt[MAX_PATH] = _T("");

	_tsplitpath_s(tmpFilePath.GetBuffer(tmpFilePath.GetLength()),
		tmpDrive, sizeof(tmpDrive) / sizeof(TCHAR),
		tmpDir, sizeof(tmpDir) / sizeof(TCHAR),
		tmpFilename, sizeof(tmpFilename) / sizeof(TCHAR),
		tmpExt, sizeof(tmpExt) / sizeof(TCHAR));

	return (CString)tmpFilename;
}

CString FileUtils::GetFileName(const CString filePath)
{
	CString tmpFilePath = filePath;
	TCHAR tmpDrive[8] = _T("");
	TCHAR tmpDir[MAX_PATH] = _T("");
	TCHAR tmpFilename[MAX_PATH] = _T("");
	TCHAR tmpExt[MAX_PATH] = _T("");

	_tsplitpath_s(tmpFilePath.GetBuffer(tmpFilePath.GetLength()),
		tmpDrive, sizeof(tmpDrive) / sizeof(TCHAR),
		tmpDir, sizeof(tmpDir) / sizeof(TCHAR),
		tmpFilename, sizeof(tmpFilename) / sizeof(TCHAR),
		tmpExt, sizeof(tmpExt) / sizeof(TCHAR));

	CString tmpName = (CString)tmpFilename + (CString)tmpExt;

	return tmpName;
}

CString FileUtils::GetFileDirectory(const CString filePath)
{
	CString tmpFilePath = filePath;
	TCHAR tmpDrive[8] = _T("");
	TCHAR tmpDir[MAX_PATH] = _T("");
	TCHAR tmpFilename[MAX_PATH] = _T("");
	TCHAR tmpExt[MAX_PATH] = _T("");

	_tsplitpath_s(tmpFilePath.GetBuffer(tmpFilePath.GetLength()),
		tmpDrive, sizeof(tmpDrive) / sizeof(TCHAR),
		tmpDir, sizeof(tmpDir) / sizeof(TCHAR),
		tmpFilename, sizeof(tmpFilename) / sizeof(TCHAR),
		tmpExt, sizeof(tmpExt) / sizeof(TCHAR));

	CString tmpName = (CString)tmpDrive + (CString)tmpDir;

	return tmpName;
}

CString FileUtils::GetDrive(const CString filePath)
{
	CString tmpFilePath = filePath;
	TCHAR tmpDrive[8] = _T("");
	TCHAR tmpDir[MAX_PATH] = _T("");
	TCHAR tmpFilename[MAX_PATH] = _T("");
	TCHAR tmpExt[MAX_PATH] = _T("");

	_tsplitpath_s(tmpFilePath.GetBuffer(tmpFilePath.GetLength()),
		tmpDrive, sizeof(tmpDrive) / sizeof(TCHAR),
		tmpDir, sizeof(tmpDir) / sizeof(TCHAR),
		tmpFilename, sizeof(tmpFilename) / sizeof(TCHAR),
		tmpExt, sizeof(tmpExt) / sizeof(TCHAR));

	return (CString)tmpDrive;
}

CString FileUtils::GetProgramPath()
{
	TCHAR tmpFilePath[MAX_PATH] = _T("");
	::GetModuleFileName(NULL, tmpFilePath, MAX_PATH);
	return (CString)tmpFilePath;
}

CString FileUtils::GetProgramDirectory()
{
	return GetFileDirectory(GetProgramPath());
}

bool FileUtils::IsExistFile(const CString filePath, const int accessMode)
{
	bool bRet = true;
	CString tmpFilePath = filePath;
	if (_taccess_s(tmpFilePath.GetBuffer(tmpFilePath.GetLength()), accessMode) != 0)
	{
		bRet = false;
	}
	return bRet;
}

bool FileUtils::IsExistFolder(const CString folderPath)
{
	bool bRet = true;
	DWORD dRet = ::GetFileAttributes(folderPath);

	if (dRet == INVALID_FILE_ATTRIBUTES)
	{
		bRet = false;
	}

	return bRet;
}



void FileUtils::MakeDirectory(const CString directory)
{
	CString tmpDirectory = directory;
	
	tmpDirectory.Replace(_T('/'), _T('\\'));
	
	if (directory.Right(1).Compare(_T("\\"))) {
		tmpDirectory += (CString)_T('\\');
	}
	CString preDirectory;
	int nStart = 0;
	int nEnd;
	while ((nEnd = tmpDirectory.Find('\\', nStart)) >= 0)
	{
		CString csToken = directory.Mid(nStart, nEnd - nStart);
		CreateDirectory(preDirectory + csToken, NULL);

		preDirectory += csToken;
		preDirectory += _T('\\');
		nStart = nEnd + 1;
	}
}

void FileUtils::copyDirectory(const CString srcPath, const CString dstPath)
{
	CString tmpSrcPath = srcPath;
	CString tmpDstPath = dstPath;

	tmpSrcPath.Replace(_T('/'), _T('\\'));
	tmpDstPath.Replace(_T('/'), _T('\\'));

	if (srcPath.Right(1).Compare(_T("\\"))) {
		tmpSrcPath += (CString)_T('\\');
	}
	if (dstPath.Right(1).Compare(_T("\\"))) {
		tmpDstPath += (CString)_T('\\');
	}
	MakeDirectory(tmpDstPath);
	tmpSrcPath += _T("*.*");
	
	CFileFind finder;
	
	BOOL bFolder = finder.FindFile(tmpSrcPath);
	while (bFolder) {
		bFolder = finder.FindNextFile();
		if (finder.IsDots()) {
			continue;
		}
		else if(finder.IsDirectory()) {
			CString nextSrc = finder.GetFilePath();
			CString nextdst = tmpDstPath + finder.GetFileName();
			copyDirectory(nextSrc, nextdst);
		} 
		else {
			CString tmpSrc = finder.GetFilePath();
			CString tmpDst = tmpDstPath + finder.GetFileName();

			::CopyFile(tmpSrc, tmpDst, false);
		}
	}
	finder.Close();
}

void FileUtils::DeleteDirectory(const CString srcPath)
{
	CString tmpSrcPath = srcPath;
	
	tmpSrcPath.Replace(_T('/'), _T('\\'));
	
	if (srcPath.Right(1).Compare(_T("\\"))) {
		tmpSrcPath += (CString)_T('\\');
	}
	
	tmpSrcPath += _T("*.*");

	CFileFind finder;

	BOOL bFolder = finder.FindFile(tmpSrcPath);
	while (bFolder) {
		bFolder = finder.FindNextFile();
		if (finder.IsDots()) {
			continue;
		}
		else if (finder.IsDirectory()) {
			DeleteDirectory(finder.GetFilePath());
		}
		else {
			DeleteFile(finder.GetFilePath());
		}
	}
	RemoveDirectory(srcPath);
	finder.Close();
}

CString FileUtils::randomString(int length)
{
	CString tmpString;

	//srand((unsigned)time(NULL));
	TCHAR randArray[37] = _T("ABCDFGHIJKLMNOPQRSNTUVWXYZ0123456789");
	for (int i = 0; i < length; i++) {
		//TCHAR temp = rand() % 25 + 65;
		
		int randomNumber = rand() % 37;
		tmpString += randArray[randomNumber];
	}
	return tmpString.MakeLower();
}

void FileUtils::fileList(const CString srcPath, const bool flag, CStringArray &list)
{
	CString tmpSrcPath = srcPath;
	
	tmpSrcPath.Replace(_T('/'), _T('\\'));
	
	if (srcPath.Right(1).Compare(_T("\\"))) {
		tmpSrcPath += (CString)_T('\\');
	}
	
	tmpSrcPath += _T("*.*");

	CFileFind finder;

	BOOL bFolder = finder.FindFile(tmpSrcPath);
	while (bFolder) {
		bFolder = finder.FindNextFile();
		if (finder.IsDots()) {
			continue;
		}
		else if (finder.IsDirectory()) {
			if(flag) {
				fileList(finder.GetFilePath(), flag, list);
			}
			else
				continue;
		}
		else {
			list.Add(finder.GetFilePath());
		}
	}
	finder.Close();
}

void FileUtils::fileCount(const CString srcPath, const CString fileExt, const bool flag, DWORD &count)
{
	CString tmpSrcPath = srcPath;
	
	tmpSrcPath.Replace(_T('/'), _T('\\'));
	
	if (srcPath.Right(1).Compare(_T("\\"))) {
		tmpSrcPath += (CString)_T('\\');
	}
	
	tmpSrcPath += _T("*.*");

	CFileFind finder;

	BOOL bFolder = finder.FindFile(tmpSrcPath);
	while (bFolder) {
		bFolder = finder.FindNextFile();
		if (finder.IsDots()) {
			continue;
		}
		else if (finder.IsDirectory()) {
			if(flag) {
				fileCount(finder.GetFilePath(), fileExt, flag, count);
			}
			else
				continue;
		}
		else {
			CString ext = GetExtName(finder.GetFilePath());
			if(ext.CompareNoCase(fileExt) == 0) 
			{
				count++;
			}
		}
	}
	finder.Close();
}

DWORD FileUtils::executeCommandLine(CString cmdLine, DWORD timeOut)
{
	DWORD dExitCode = 0;

	PROCESS_INFORMATION processInformation = {0};
	STARTUPINFO startupInfo                = {0};
	startupInfo.cb                         = sizeof(startupInfo);
	int nStrBuffer                         = cmdLine.GetLength() + 50;


	// Create the process
	BOOL result = CreateProcess(NULL, cmdLine.GetBuffer(nStrBuffer), 
		NULL, NULL, FALSE, 
		NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, 
		NULL, NULL, &startupInfo, &processInformation);
	cmdLine.ReleaseBuffer();

	if (!result)
	{
		// CreateProcess() failed
		// Get the error from the system
		LPVOID lpMsgBuf;
		DWORD dw = GetLastError();
		FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 
			NULL, dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpMsgBuf, 0, NULL);

		// Display the error
		CString strError = (LPTSTR) lpMsgBuf;
		TRACE(_T("::executeCommandLine() failed at CreateProcess()\nCommand=%s\nMessage=%s\n\n"), cmdLine, strError);

		// Free resources created by the system
		LocalFree(lpMsgBuf);

		return -1;
	}
	else
	{
		// Successfully created the process.  Wait for it to finish.
		WaitForSingleObject(processInformation.hProcess, INFINITE );

		// Get the exit code.
		result = GetExitCodeProcess(processInformation.hProcess, &dExitCode);

		// Close the handles.
		CloseHandle( processInformation.hProcess );
		CloseHandle( processInformation.hThread );

		if (!result)
		{
			// TerminateProcess(processInformation.hProcess, (UINT) -1);
			TRACE(_T("Executed command but couldn't get exit code.\nCommand=%s\n"), cmdLine);
			return -1;
		}
	}

	return dExitCode;
}

bool FileUtils::writeTextFile(CString strFilePath, CStringArray &contents, UINT encoding)
{
	int nRet = _taccess_s(strFilePath.GetBuffer(strFilePath.GetLength()), 6);

	if(nRet == 0)
		::DeleteFile(strFilePath);

	CFile file;

	bool bRet = false;

	try
	{
		if(file.Open(strFilePath, CFile::modeCreate |CFile::modeReadWrite))
		{
			for(int i = 0 ; i < contents.GetSize() ; i++)
			{
				CString tmpContent = contents.GetAt(i) + _T("\r\n");
				CStringA strEncoding = CW2A(tmpContent, encoding);
				file.Write(strEncoding.GetBuffer(strEncoding.GetLength()), strEncoding.GetLength());
			}

			file.Flush();
			file.Close();

			bRet = true;
		}
	}
	catch(...)
	{
	}

	return bRet;
}

bool FileUtils::readTextFile(CString strFilePath, CStringArray &contents, UINT encoding)
{
	int nRet = _taccess_s(strFilePath.GetBuffer(strFilePath.GetLength()), 6);

	if(nRet != 0)
		return false;

	CStdioFile stdioFile;

	bool bRet = false;

	try
	{
		if(stdioFile.Open(strFilePath, CFile::modeRead))
		{
			CString buffer;
			while(stdioFile.ReadString(buffer) != NULL)
			{
				contents.Add(buffer);
			}

			stdioFile.Flush();
			stdioFile.Close();

			bRet = true;
		}
	}
	catch(...)
	{
	}

	return bRet;
}



int stringUtils::SplitString(CString str, CString var, CStringArray &strs)
{
	int length = str.GetLength();
	if (length == 0) {
		return 0;
	}
	int count = 1;
	CString tempStr = str;
	int splitNameLength = var.GetLength();

	while (length) {
		int find = tempStr.Find(var);
		if (find != -1) {
			CString temp = tempStr.Left(find);
			strs.Add(temp);
			tempStr = tempStr.Mid(find + splitNameLength);
			count++;
		}
		else {
			strs.Add(tempStr);
			length = 0;
		}
	}
	return count;
}